package com.ushine.web.base.facade.impl;

import com.ushine.web.base.facade.IUserRolePermissionFacade;
import com.ushine.web.base.model.redis.UserRedisBO;
import com.ushine.web.base.model.system.DataPermissionDO;
import com.ushine.web.base.model.system.UserDO;
import com.ushine.web.base.facade.IUserRedisFacade;
import com.ushine.web.component.authority.DataFilterTypeEnum;
import com.ushine.web.component.contant.RedisConstant;
import com.ushine.web.component.exception.ServiceException;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: yls
 * @Date: 2022/02/21 16:24
 * @Description:
 * @Version 1.0
 */
@Service
public class UserRedisFacadeImpl implements IUserRedisFacade {

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private IUserRolePermissionFacade userRolePermissionFacade;

    @Override
    public Boolean insertUserInfo(UserDO user) {
        String username = user.getUsername();
        RBucket<UserRedisBO> userRedisBucket = getUserRedisBucket(username);
        if (userRedisBucket.isExists()) {
            // 删除旧的缓存信息
            userRedisBucket.delete();
        }
        UserRedisBO userRedis = getUserRedisByUser(user);
        userRedisBucket.set(userRedis);
        return true;
    }

    @Override
    public Boolean deleteUserInfo(String username) {
        RBucket<UserRedisBO> userRedisBucket = getUserRedisBucket(username);
        if (userRedisBucket.isExists()) {
            return userRedisBucket.delete();
        }
        return true;
    }

    @Override
    public UserRedisBO getUserInfo(String username) throws ServiceException {
        RBucket<UserRedisBO> userRedisBucket = getUserRedisBucket(username);
        if (userRedisBucket.isExists()) {
            UserRedisBO userRedis = userRedisBucket.get();
            if (userRedis.getId() != null) {
                return userRedis;
            }
        }

        UserDO user = userRolePermissionFacade.listUserAllPermissions(username);
        UserRedisBO userRedis = getUserRedisByUser(user);
        userRedisBucket.set(userRedis);
        return userRedis;
    }

    @Override
    public UserRedisBO getLoginUserInfo(String username) throws ServiceException {
        RBucket<UserRedisBO> userRedisBucket = getUserRedisBucket(username);
        UserDO user = userRolePermissionFacade.listUserAllPermissions(username);
        UserRedisBO userRedis = getUserRedisByUser(user);
        userRedisBucket.set(userRedis);
        return userRedis;
    }

    @Override
    public DataPermissionDO getUserDataPermission(String username, String functionName) throws ServiceException {
        Map<String, DataPermissionDO> dataPermissionMap = getUserInfo(username).getDataPermissionMap();
        dataPermissionMap = Optional.ofNullable(dataPermissionMap).orElse(new HashMap<>(1));
        if (dataPermissionMap.containsKey(functionName)) {
            return dataPermissionMap.get(functionName);
        }
        /*
         * 如果未查到对应的权限信息
         */
        DataPermissionDO dataPermission = new DataPermissionDO();
        dataPermission.setFilterType(DataFilterTypeEnum.SELF_CREATE.getType());
        dataPermission.setCustomExpression("1 = 1");
        dataPermission.setOrgId(-1L);
        dataPermission.setOrgIds("-1");
        return dataPermission;
    }

    /**
     * 功能描述:
     * 〈 将数据库存储的用户信息转化为redis格式的数据缓存 〉
     *
     * @param user 用户信息
     * @return : com.ushine.web.base.model.redis.UserRedisBO
     * @author : yls
     * @date : 2022/02/21 16:48
     */
    private UserRedisBO getUserRedisByUser(UserDO user) {
        UserRedisBO userRedis = new UserRedisBO();
        userRedis.setId(user.getId());
        userRedis.setRoleNames(user.getRoleNames());
        userRedis.setUsername(user.getUsername());
        userRedis.setPassword(user.getPassword());
        userRedis.setAccountNonExpired(user.isAccountNonExpired());
        userRedis.setCredentialsNonExpired(user.isAccountNonExpired());
        userRedis.setAccountNonLocked(user.isAccountNonLocked());
        userRedis.setEnabled(user.isEnabled());
        userRedis.setFunctionPermissions(user.getFunctionPermissions());
        /*
         * 组装数据权限
         */
        List<DataPermissionDO> dataPermissions = user.getDataPermissions();
        dataPermissions = Optional.ofNullable(dataPermissions).orElse(new ArrayList<>(0));
        Map<String, DataPermissionDO> dataPermissionMap = dataPermissions.stream().collect(Collectors.toMap(DataPermissionDO::getDataPermissionName, dataPermissionDO -> dataPermissionDO));
        userRedis.setDataPermissionMap(dataPermissionMap);
        return userRedis;
    }

    /**
     * 功能描述:
     * 〈 组装用户在缓存中的通道 〉
     *
     * @param username 用户名
     * @return : org.redisson.api.RBucket<com.ushine.web.base.model.redis.UserRedisBO>
     * @author : yls
     * @date : 2022/02/21 16:50
     */
    private RBucket<UserRedisBO> getUserRedisBucket(String username) {
        return redissonClient.getBucket(RedisConstant.USER_INFO_PREFIX + RedisConstant.LOCK_SEPARATOR + username);
    }
}
